/* -*- coding: utf-8; tab-width: 4 -*-
vim: ts=4 noet ai */

/**
	Desktopd Rainbow Persona -- Colorful Firefox

	Copyright © 2016  Desktopd Project

	This program is free software: you can redistribute it and/or modify
	it under the terms of the GNU General Public License as
	published by the Free Software Foundation, either version 3 of the
	License, or (at your option) any later version.

	This program is distributed in the hope that it will be useful,
	but WITHOUT ANY WARRANTY; without even the implied warranty of
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
	GNU General Public License for more details.

	You should have received a copy of the GNU General Public License
	along with this program.  If not, see <http://www.gnu.org/licenses/>.

	@license GPL-3.0+
	@file
*/

'use strict';

const xyz = require ('./CIEXYZ');

const _u = (X, Y, Z) => X ? 4 * X / (X + 15 * Y + 3 * Z) : 0;
const _v = (X, Y, Z) => Y ? 9 * Y / (X + 15 * Y + 3 * Z) : 0;

/**
	L*, u*, v* values
	R, G, and B are in [0, 1]
*/
exports.fromRGB = (Xn, Yn, Zn, r, g, b) => {
	const [X, Y, Z] = xyz.fromRGB (r, g, b);
	const y = Y / Yn;
	const L = y > 0.008856451679035631
		? 116 * Math.pow (y, 1 / 3) - 16
		: 903.2962962962961 * y;
	const U = 13 * L * (_u (X, Y, Z) - _u (Xn, Yn, Zn));
	const V = 13 * L * (_v (X, Y, Z) - _v (Xn, Yn, Zn));
	return [L, U, V];
};

/**
	R, G, B values
	Inverse of the above
	Note: Resulting RGB may be out of range
*/
exports.toRGB = (Xn, Yn, Zn, L, U, V) => {
	const u = U / (13 * L) + _u (Xn, Yn, Zn);
	const v = V / (13 * L) + _v (Xn, Yn, Zn);
	const Y = L > 8 ? Yn * Math.pow((L + 16) / 116, 3) : Yn * L * 0.0011070564598794539;
	const X = Y * 2.25 * u / v;
	const Z = Y * (12 - 3 * u - 20 * v) / (4 * v);
	return xyz.toRGB (X, Y, Z);
};

